home *** CD-ROM | disk | FTP | other *** search
- #include "xinternl.h"
- #include <conio.h>
- #include <mem.h>
-
- /*==================================================================
- XPLAIN.CPP contains the basic functions for pixel-resolution collision
- detection in mode X.
-
- These routines were written initially by Tiaan A Geldenhuys and
- company and modified March 1995 by Victor B. Putz.
- ===================================================================*/
-
- extern xScreenCoord_t TopClip;
- extern xScreenCoord_t BottomClip;
-
- int CollideX;
- int CollideY;
-
- void x_pbm_to_plain( /* Convert from planar bitmap to plain bitmap */
- BYTE * pbSource,
- BYTE * pbDest,
- xColor_t ColorMask
- )
- {
- int iNibbleWidth = *pbSource++;
- int iHeight = *pbSource++;
- //round up our nibble width to get byte width
- int iByteWidth = ( iNibbleWidth + 1 ) / 2;
- *pbDest++ = ( BYTE )iByteWidth;
- *pbDest++ = ( BYTE )iHeight;
- //store the location of the bitmap, since we come to it every plane
- BYTE * pbDestRef = pbDest;
- memset( pbDest, 0, iByteWidth * iHeight );
- BYTE bHighPixMask = 0x80;
- BYTE bLowPixMask = 0x08;
- //now copy the pixels to bits
- for ( int iPlaneCounter = 0; iPlaneCounter < 4; ++iPlaneCounter ) {
- pbDest = pbDestRef;
- for ( int iHeightCounter = 0; iHeightCounter < iHeight; ++iHeightCounter ) {
- for ( int iWidthCounter = 0; iWidthCounter < iNibbleWidth; ++iWidthCounter ) {
- int iTest = *pbSource++;
- if ( iTest & ColorMask ) {
- *pbDest |= bHighPixMask;
- }
- ++iWidthCounter;
- if ( iWidthCounter < iNibbleWidth ) {
- iTest = *pbSource++;
- if ( iTest & ColorMask ) {
- *pbDest |= bLowPixMask;
- }
- }
- ++pbDest;
- }
- }
- bHighPixMask >>= 1;
- bLowPixMask >>= 1;
- }
-
- }
-
-
-
- char x_check_collision_plain(
- BYTE *VicStruct1,
- int X1,
- int Y1,
- BYTE *VicStruct2,
- int X2,
- int Y2
- )
- {
- //rearrange so that VicStruct1 is Leftmost
- if ( X1 > X2 ) {
- int iTemp = X2;
- X2 = X1;
- X1 = iTemp;
- iTemp = Y2;
- Y2 = Y1;
- Y1 = iTemp;
- BYTE * pbTemp = VicStruct2;
- VicStruct2 = VicStruct1;
- VicStruct1 = pbTemp;
- }
- //now that we're assured VicStruct1 is leftmost, get width and height
- int iWidth1 = *VicStruct1++;
- int iHeight1 = *VicStruct1++;
- int iWidth2 = *VicStruct2++;
- int iHeight2 = *VicStruct2++;
- //First, just check for a rectangular collision
- //get the offset into the first map of the second map
- int iXOffset = X2 - X1;
- //we know there's a collision; now let's turn the X offset from a pixel
- //offset to a byte offset and get a "right shift" to see how many
- //bits to the right we need to shift VicStruct1's data
- int iRightShift = iXOffset & 0x07;
- // iXOffset &= 0xfff8;
- iXOffset >>= 3;
- //if we're past the first map, return
- if ( iXOffset > iWidth1 ) {
- return 0;
- }
- //now check the Y part
- int iYOffset = Y2 - Y1;
- if ( iYOffset > iHeight1 ) {
- return 0;
- }
- if ( ( iYOffset + iHeight2 ) < 0 ) {
- return 0;
- }
-
- if ( iYOffset < 0 ) {
- iYOffset *= -1;
- }
- //Well, now we get to the nitty gritty pixel-based detection.
- //this will be messy code, because I don't have time to do it well.
- //in most cases, the rectangular collision detection will reduce
- //the time necessary. If it becomes an issue I'll look at it.
- int iXToCheck = iWidth1 - iXOffset;
- if ( iXToCheck > iWidth2 ) {
- iXToCheck = iWidth2;
- }
- int iSkip1 = iWidth1 - iXToCheck;
- int iSkip2 = iWidth2 - iXToCheck;
-
- int iYToCheck = 0;
- BYTE * pb1 = VicStruct1;
- BYTE * pb2 = VicStruct2;
- if ( Y1 <= Y2 ) {
- iYToCheck = iHeight1 - iYOffset;
- if ( iYToCheck > iHeight2 ) {
- iYToCheck = iHeight2;
- }
- pb1 += iYOffset * iWidth1 + iXOffset;
- pb2 += 0;
- }
- else {
- iYToCheck = iHeight2 - iYOffset;
- if ( iYToCheck > iHeight1 ) {
- iYToCheck = iHeight1;
- }
- pb1 += iXOffset;
- pb2 += iYOffset * iWidth2;
- }
- while( iYToCheck-- ) {
- int iCheck1 = 0;
- int iCheck2 = 0;
- int iXCount = iXToCheck;
- while( iXCount-- ) {
- iCheck1 += *pb1++;
- iCheck2 += *pb2++;
- if ( ( iCheck1 << iRightShift ) & iCheck2 ) {
- return 1;
- }
- iCheck1 <<= 8;
- iCheck2 <<= 8;
- }
- pb1 += iSkip1;
- pb2 += iSkip2;
- }
- return 0;
- }
-
-
-
- BYTE abFlipTable[] = {
- 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
- 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f
- };
-
- extern BYTE * pbVGABuffer;
- extern int ScrnLogicalByteWidth;
- extern BYTE abMirrorTable[];
- extern WORD awTextMask[];
- /*
- Copy a VIC bitmap (variable size) from SRAM to VRAM.
-
- Clips in Y direction only, and does not clip both top and bottom ( ie if
- the top is clipped, bottom is not ).
- */
- void x_put_plain(
- int X,
- int Y,
- xPageHandle_t ScrnOffs,
- BYTE * VicStruct,
- xColor_t Color
- )
- {
- BYTE * pbDest = pbVGABuffer + ScrnOffs + ( ScrnLogicalByteWidth * Y ) + X / 4;
- BYTE * pbSource = VicStruct;
- int iByteWidth = *pbSource++;
- int iHeight = *pbSource++;
- int iSkip = ScrnLogicalByteWidth - ( iByteWidth * 2 );
- //clip in Y direction
- //clip top
- int iHeightToPut = iHeight;
- if ( Y < TopClip ) {
- iHeightToPut = ( Y + iHeight ) - TopClip;
- if ( iHeightToPut <= 0 ) {
- return;
- }
- //now update pbSource to look at the new start
- pbSource += ( TopClip - Y ) * iSkip;
- pbDest = pbVGABuffer + ScrnOffs + ( ScrnLogicalByteWidth * TopClip ) + X / 4;
- }
- else if ( ( Y + iHeight ) > BottomClip ) {
- iHeightToPut = BottomClip - Y;
- if ( iHeightToPut <= 0 ) {
- return;
- }
- }
- int iRotation = ( X & 3 );
- outp( SC_INDEX, MAP_MASK );
- int iTemp = 0;
- for( int iRowCounter = 0; iRowCounter < iHeightToPut; ++iRowCounter ) {
- for ( int iColumnCounter = 0; iColumnCounter < iByteWidth; ++iColumnCounter ) {
- iTemp = *pbSource++;
- iTemp = abMirrorTable[ iTemp ];
- iTemp <<= iRotation;
- //TEST STUFF!
- outpw( SC_INDEX, awTextMask[ iTemp & 0x0f ] );
- *pbDest++ = ( BYTE )Color;
- outpw( SC_INDEX, awTextMask[ ( iTemp & 0xf0 ) >> 4 ] );
- *pbDest++ = ( BYTE )Color;
- outpw( SC_INDEX, awTextMask[ iTemp >> 8 ] );
- *pbDest = ( BYTE )Color;
- }
- pbDest += iSkip;
- }
- }
-
-